home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.0 KB  |  316 lines

  1. /*
  2.     dwarf_util.c
  3.     $Revision: 1.26 $   $Date: 1993/08/16 23:22:03 $
  4.  
  5.     Dwarf utility functions.
  6. */
  7.  
  8.  
  9. #include <stdio.h>
  10. #include "dwarf_incl.h"
  11. #include "dwarf_die_deliv.h"
  12.  
  13.  
  14. /*
  15.     decode ULEB
  16. */
  17. Dwarf_Unsigned
  18. _dwarf_decode_u_leb128 (
  19.     Dwarf_Small         *leb128,
  20.     Dwarf_Word          *leb128_length
  21. )
  22. {
  23.     Dwarf_Small         byte;
  24.     Dwarf_Word        word_number;
  25.     Dwarf_Unsigned      number;
  26.     Dwarf_Sword      shift;
  27.     Dwarf_Sword        byte_length;
  28.  
  29.     if ((*leb128 & 0x80) == 0) {
  30.     if (leb128_length != NULL) *leb128_length = 1;
  31.     return(*leb128);
  32.     }
  33.     else if ((*(leb128 + 1) & 0x80) == 0) {
  34.     if (leb128_length != NULL) *leb128_length = 2;
  35.  
  36.     word_number = *leb128 & 0x7f;
  37.     word_number |= (*(leb128 + 1) & 0x7f) << 7;
  38.     return(word_number);
  39.     }
  40.     else if ((*(leb128 + 2) & 0x80) == 0) {
  41.     if (leb128_length != NULL) *leb128_length = 3;
  42.  
  43.     word_number = *leb128 & 0x7f;
  44.     word_number |= (*(leb128 + 1) & 0x7f) << 7;
  45.     word_number |= (*(leb128 + 2) & 0x7f) << 14;
  46.     return(word_number);
  47.     }
  48.     else if ((*(leb128 + 3) & 0x80) == 0) {
  49.     if (leb128_length != NULL) *leb128_length = 4;
  50.  
  51.     word_number = *leb128 & 0x7f;
  52.     word_number |= (*(leb128 + 1) & 0x7f) << 7;
  53.     word_number |= (*(leb128 + 2) & 0x7f) << 14;
  54.     word_number |= (*(leb128 + 3) & 0x7f) << 21;
  55.     return(word_number);
  56.     }
  57.  
  58.     number = 0;
  59.     shift = 0;
  60.     byte_length = 1;
  61.     byte = *(leb128);
  62.     while (true) {
  63.     number |= (byte & 0x7f) << shift;
  64.     shift += 7;
  65.  
  66.     if ((byte & 0x80) == 0) {
  67.         if (leb128_length != NULL) *leb128_length = byte_length;
  68.         return(number);
  69.     }
  70.  
  71.     byte_length++;
  72.     byte = *(++leb128);
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.     decode SLEB
  79. */
  80. Dwarf_Signed
  81. _dwarf_decode_s_leb128 (
  82.     Dwarf_Small         *leb128,
  83.     Dwarf_Word          *leb128_length
  84. )
  85. {
  86.     Dwarf_Small         byte = *leb128;
  87.     Dwarf_Sword        word_number = 0;
  88.     Dwarf_Signed        number;
  89.     Dwarf_Bool            sign = 0;
  90.     Dwarf_Bool        ndone = true;
  91.     Dwarf_Sword      shift = 0;
  92.     Dwarf_Sword        byte_length = 0;
  93.  
  94.     while (byte_length++ < 4) {
  95.     sign = byte & 0x40;
  96.     word_number |= (byte & 0x7f) << shift;
  97.     shift += 7;
  98.  
  99.     if ((byte & 0x80) == 0) {
  100.         ndone = false;
  101.         break;
  102.     }
  103.     byte = *(++leb128);
  104.     }
  105.  
  106.     number = word_number;
  107.     while (ndone) {
  108.     sign = byte & 0x40;
  109.         number |= (byte & 0x7f) << shift;
  110.         shift += 7;
  111.  
  112.     if ((byte & 0x80) == 0) {
  113.         break;
  114.     }
  115.  
  116.         /* 
  117.         Increment after byte has been placed in
  118.             number on account of the increment already
  119.             done when the first loop terminates.  That
  120.             is the fourth byte is picked up and byte_length
  121.             updated in the first loop.  So increment not
  122.             needed in this loop if break is taken.
  123.         */
  124.     byte_length++;
  125.         byte = *(++leb128);
  126.     }
  127.  
  128.     if ((shift < sizeof(Dwarf_Signed)*8) && sign) 
  129.     number |= - (1 << shift);
  130.  
  131.     if (leb128_length != NULL) *leb128_length = byte_length;
  132.     return(number);
  133. }
  134.  
  135.  
  136. /*
  137.     Given a form, and a pointer to the bytes encoding 
  138.     a value of that form, val_ptr, this function returns
  139.     the length, in bytes, of a value of that form.
  140.     When using this function, check for a return of 0
  141.     a recursive DW_FORM_INDIRECT value.
  142. */
  143. Dwarf_Unsigned
  144. _dwarf_get_size_of_val (
  145.     Dwarf_Debug        dbg,
  146.     Dwarf_Unsigned      form,
  147.     Dwarf_Small         *val_ptr
  148. )
  149. {
  150.     Dwarf_Unsigned      length;
  151.     Dwarf_Word        leb128_length;
  152.     Dwarf_Unsigned      form_indirect;
  153.     Dwarf_Unsigned    ret_value;
  154.  
  155.     switch (form) {
  156.  
  157.     default :            /* Handles form = 0. */
  158.         return(form);
  159.  
  160.         case DW_FORM_addr:  
  161.         case DW_FORM_ref_addr:   
  162.             return(dbg->de_length_size);
  163.  
  164.     case DW_FORM_block1:
  165.         return(*(Dwarf_Small *)val_ptr + 1);
  166.  
  167.         case DW_FORM_block2:
  168.         READ_UNALIGNED(ret_value, val_ptr, sizeof(Dwarf_Half));
  169.         return(ret_value + sizeof(Dwarf_Half));
  170.  
  171.         case DW_FORM_block4:
  172.         READ_UNALIGNED(ret_value, val_ptr, sizeof(Dwarf_Word));
  173.         return(ret_value + sizeof(Dwarf_Word));
  174.  
  175.     
  176.         case DW_FORM_data1:
  177.             return(1);
  178.  
  179.         case DW_FORM_data2:
  180.             return(2);
  181.  
  182.         case DW_FORM_data4:
  183.             return(4);
  184.  
  185.         case DW_FORM_data8:
  186.             return(8);
  187.  
  188.         case DW_FORM_string:
  189.             return(strlen(val_ptr) + 1);
  190.  
  191.         case DW_FORM_block:
  192.             length = _dwarf_decode_u_leb128(val_ptr,&leb128_length);
  193.             return(length + leb128_length);
  194.  
  195.         case DW_FORM_flag:
  196.             return(1);
  197.  
  198.         case DW_FORM_indirect:
  199.             form_indirect = _dwarf_decode_u_leb128(val_ptr,&leb128_length);
  200.             if (form_indirect == DW_FORM_indirect) return(0);
  201.             return(leb128_length + _dwarf_get_size_of_val(dbg, form_indirect,
  202.             val_ptr+leb128_length));
  203.  
  204.         case DW_FORM_ref1:
  205.         return(1);
  206.  
  207.     case DW_FORM_ref2:
  208.         return(2);
  209.  
  210.     case DW_FORM_ref4:
  211.         return(4);
  212.  
  213.     case DW_FORM_ref8:
  214.         return(8);
  215.  
  216.         case DW_FORM_sdata: 
  217.             _dwarf_decode_s_leb128(val_ptr,&leb128_length);
  218.             return(leb128_length);
  219.  
  220.         case DW_FORM_strp:
  221.             return(dbg->de_length_size);
  222.  
  223.         case DW_FORM_udata: 
  224.             _dwarf_decode_u_leb128(val_ptr,&leb128_length);
  225.             return(leb128_length);
  226.     }
  227. }
  228.  
  229.  
  230. /*
  231.     This function returns a pointer to a Dwarf_Abbrev_List_s
  232.     struct for the abbrev with the given code.  It puts the
  233.     struct on the appropriate hash table.  It also adds all
  234.     the abbrev between the last abbrev added and this one to
  235.     the hash table.  In other words, the .debug_abbrev section
  236.     is scanned sequentially from the top for an abbrev with
  237.     the given code.  All intervening abbrevs are also put 
  238.     into the hash table.
  239.  
  240.     This function hashes the given code, and checks the chain
  241.     at that hash table entry to see if a Dwarf_Abbrev_List_s
  242.     with the given code exists.  If yes, it returns a pointer
  243.     to that struct.  Otherwise, it scans the .debug_abbrev
  244.     section from the last byte scanned for that CU till either
  245.     an abbrev with the given code is found, or an abbrev code
  246.     of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all
  247.     abbrev's read till that point into the hash table.  The
  248.     hash table contains both a head pointer and a tail pointer
  249.     for each entry.
  250.  
  251.     Returns NULL on error.
  252. */
  253. Dwarf_Abbrev_List
  254. _dwarf_get_abbrev_for_code (
  255.     Dwarf_CU_Context    cu_context,
  256.     Dwarf_Word        code
  257. )
  258. {
  259.     Dwarf_Debug        dbg = cu_context->cc_dbg;
  260.     Dwarf_Hash_Table    hash_table = cu_context->cc_abbrev_hash_table;
  261.     Dwarf_Word        hash_num;
  262.     Dwarf_Abbrev_List    hash_abbrev_list;
  263.     Dwarf_Abbrev_List    abbrev_list;
  264.     Dwarf_Byte_Ptr    abbrev_ptr;
  265.     Dwarf_Half        abbrev_code, abbrev_tag;
  266.     Dwarf_Half        attr_name, attr_form;
  267.  
  268.     hash_num = code % ABBREV_HASH_TABLE_SIZE;
  269.     for (hash_abbrev_list = hash_table[hash_num].at_head; 
  270.     hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code; 
  271.         hash_abbrev_list = hash_abbrev_list->ab_next);
  272.     if (hash_abbrev_list != NULL)
  273.         return(hash_abbrev_list);
  274.  
  275.     abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ? 
  276.     cu_context->cc_last_abbrev_ptr : 
  277.     dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
  278.  
  279.     /* End of abbrev's for this cu, since abbrev code is 0. */
  280.     if (*abbrev_ptr == 0) return(NULL);
  281.  
  282.     do {
  283.         DECODE_LEB128_UWORD(abbrev_ptr, abbrev_code)
  284.     DECODE_LEB128_UWORD(abbrev_ptr, abbrev_tag)
  285.  
  286.         abbrev_list = (Dwarf_Abbrev_List)
  287.         _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
  288.         if (abbrev_list == NULL) return(NULL);
  289.  
  290.     hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
  291.     if (hash_table[hash_num].at_head == NULL) {
  292.         hash_table[hash_num].at_head = 
  293.         hash_table[hash_num].at_tail = abbrev_list;
  294.     }
  295.     else {
  296.         hash_table[hash_num].at_tail->ab_next = abbrev_list;
  297.         hash_table[hash_num].at_tail = abbrev_list;
  298.     }
  299.  
  300.         abbrev_list->ab_code = abbrev_code;
  301.     abbrev_list->ab_tag = abbrev_tag;
  302.  
  303.     abbrev_list->ab_has_child = *(abbrev_ptr++);
  304.         abbrev_list->ab_abbrev_ptr = abbrev_ptr;
  305.  
  306.     do {
  307.         DECODE_LEB128_UWORD(abbrev_ptr, attr_name)
  308.         DECODE_LEB128_UWORD(abbrev_ptr, attr_form)
  309.         } while (attr_name != 0 && attr_form != 0);
  310.  
  311.     } while (*abbrev_ptr != 0 && abbrev_code != code);
  312.  
  313.     cu_context->cc_last_abbrev_ptr = abbrev_ptr;
  314.     return(abbrev_code == code ? abbrev_list : NULL);
  315. }
  316.